home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1994 November / Cd Ware (Nro. 2) - Epimundo.iso / DOS / PG / CHART.ZIP / CSUB1.86 < prev    next >
Encoding:
Text File  |  1993-10-25  |  32.1 KB  |  1,165 lines

  1.  
  2.         ;write leading stem to screen
  3.  
  4. write_stem:
  5.         mov al,'║'    ;load stem character
  6. a1:
  7.         call cursor    ;position cursor
  8.         call write_chr    ;write stem character to screen
  9.         inc dh    ;increment row
  10.         loop a1    ;decrement loop count
  11.         ret    ;exit
  12.  
  13.         ;write stem character and route/subchart indicators to screen
  14.  
  15. write_indicator:
  16.         mov dx,w cursor_pos    ;load cursor coordinates
  17.         inc b cursor_pos+1    ;increment row
  18.         call cursor    ;position cursor
  19.         mov si,o indicator    ;load offset to string
  20. a1:
  21.         lodsb    ;read character from string
  22.         or al,al    ;end of string?
  23.         je ret    ;exit if it is
  24.         call write_chr    ;write character to screen
  25.         jmp a1    ;read next character
  26.  
  27.         ;get inverse sign in ax
  28.  
  29. inv_sgn:
  30.         or ax,ax    ;is value zero?
  31.         je >a1    ;exit with one in ax if it is
  32.         xor ax,ax    ;load zero
  33.         ret    ;exit
  34. a1:
  35.         mov ax,1    ;load one
  36.         ret    ;exit
  37.  
  38.         ;get sign in ax
  39.  
  40. sgn:
  41.         or ax,ax    ;is value zero?
  42.         je ret    ;exit with one in ax if it is
  43.         mov ax,1    ;load one
  44.         ret    ;exit
  45.  
  46.         ;copy current box routes
  47.  
  48. get_current_routes:
  49.         push ax    ;save register
  50.         mov ax,bp    ;load current box
  51.         jmp >a1    ;copy its routes
  52.  
  53.         ;copy routes from box to routes store
  54.  
  55. get_routes:
  56.         push ax    ;save register
  57. a1:
  58.         push cx,dx,si,di,ds,es    ;save registers
  59.         mov dx,ax    ;save box
  60.         call get_box    ;get box pointer
  61.         mov si,di    ;copy offset
  62.         mov ds,ax,es    ;copy segment
  63.         mov es,ax,cs    ;copy code segment
  64.         mov di,o routes    ;load offset to routes store
  65.         movsw    ;copy neighbour box
  66.  
  67.         ;copy routes data
  68.  
  69.         lodsw    ;load yes route
  70.         cmp ax,dx    ;is it a outstanding route?
  71. if e        xor ax,ax    ;clear route
  72.         stosw    ;store route
  73.         lodsw    ;load no route
  74.         cmp ax,dx    ;is it a outstanding route?
  75. if e        mov ax,1    ;flag decision box if it is
  76.         stosw    ;store route
  77.  
  78.         ;copy subchart markers
  79.  
  80.         movsw    ;copy child chart pointer
  81.         movsw    ;copy parent box pointer
  82.         pull es,ds,di,si,dx,cx,ax    ;restore registers
  83.         ret    ;exit
  84.  
  85.         ;get total real routes from current box
  86.  
  87. get_current_real_routes:
  88.         mov ax,bp    ;load current box
  89.         call get_routes    ;copy routes from box to store
  90.         push ax,bx,cx,si    ;save registers
  91.         mov si,no    ;load offset to routes data
  92.         mov w real_routes,0    ;clear real routes count
  93.  
  94.         ;get real routes count
  95.  
  96. a1:
  97.         mov ax,w[si+routes]    ;load box from route
  98.         cmp ax,first_box    ;is there a route?
  99.         jbe >a2    ;decrement loop count if not
  100.         inc w real_routes    ;increment count
  101.         mov w first_route,si    ;save route
  102.  
  103.         ;move to next route
  104.  
  105. a2:
  106.         sub si,2    ;move down a route
  107.         jne a1    ;decrement loop count
  108.         pull si,cx,bx,ax    ;restore registers
  109.         ret    ;exit
  110.  
  111.         ;position cursor for command line
  112.  
  113. write_command_line:
  114.         push cx,si    ;save option string length
  115.         mov cx,di    ;load offset to end of string
  116.         sub cx,o command_line    ;calculate length of string
  117.         jcxz >b1    ;exit if command line is empty
  118.         mov dl,80    ;load maximum screen width
  119.         sub dl,cl    ;subtract line length from it
  120.         shr dl,1    ;calculate column
  121.         mov dh,b cursor_pos+1    ;load row
  122.         inc b cursor_pos+1    ;increment row
  123.  
  124.         ;position cursor and load offset to start of options
  125.  
  126.         call cursor    ;position cursor
  127.         mov si,o command_line    ;load offset to string
  128.         mov di,si    ;clear string
  129.  
  130.         ;load and write character to screen
  131.  
  132. a1:
  133.         mov dl,novid    ;store normal video attribute
  134.         cmp w[si-2],' .'    ;is it option character
  135. if e        mov dl,revid    ;load reverse video attribute if it is
  136.         mov b attribute,dl    ;store attribute
  137.         lodsb    ;load character from string
  138.         call write_chr    ;write it to screen
  139.         loop a1    ;decrement loop count
  140. b1:
  141.         pull si,cx    ;restore option string offset and count
  142.         ret    ;exit
  143.  
  144.         ;clear bottom lines
  145.  
  146. clear_line:
  147.         mov dx,01700h    ;load cursor coordinates
  148.         mov al,' '    ;load space character
  149.     cs    mov bh,active_page    ;load current video page
  150.         mov bl,novid    ;load attribute
  151.         call >a1    ;clear last but one line
  152.         mov dx,01800h    ;load cursor coordinates
  153.  
  154.         ;clear line
  155.  
  156. a1:
  157.         push cx    ;save register
  158.         call cursor    ;position cursor
  159.         mov cx,80    ;load line count
  160. a1:
  161.         call write_chr    ;clear row
  162.         loop a1    ;decrement loop count
  163.         pull cx    ;restore register
  164.         ret    ;exit
  165.  
  166.         ;clear options array
  167.  
  168. clear_options:
  169.         mov cx,option_count+2    ;load option count
  170.         mov di,o option_array    ;load offset to array
  171.         mov es,ax,cs    ;copy code segment
  172.         xor ax,ax    ;clear register
  173.         rep
  174.         stosw    ;clear options array
  175.         ret    ;exit
  176.  
  177.         ;write current non-attached route to stem
  178.  
  179. write_route_stem:
  180.         mov al,'('    ;write route marker to stem string
  181.         shr bx,1    ;calculate offset to key
  182.         add bx,5
  183.         mov ah,b[bx+keys]    ;load key option
  184.         mov w route_string,ax
  185.         mov al,')'    ;load close bracket
  186.         mov b route_string+2,al    ;store it
  187.         ret    ;exit
  188.  
  189.         ;set variables for route selection
  190.  
  191. set_mode_2:
  192.         mov w insert_mode,2    ;set mode
  193.         mov bx,w current_route    ;load current route
  194.         call write_route_stem    ;put it in stem string
  195.         mov b chart_flag,1    ;set chart entry flag
  196.         stc    ;exit to chart loop
  197.         ret
  198.  
  199.         ;check if any routes left in box
  200.  
  201. check_decision_flag:
  202.         mov w branch_route_count,0    ;clear flag
  203.         cmp w current_route,0    ;is box decision box?
  204.         je >a1    ;check insert mode flag if not
  205.         mov ax,bp    ;load current box
  206.         call get_box    ;get box pointer
  207.     es    cmp w[di+no],0    ;is neither route set?
  208.         jne >a1    ;check insert mode if not
  209.     es    mov w[di+no],1    ;indicate box is decision box
  210.  
  211.         ;check if insert mode is on
  212.  
  213. a1:
  214.         mov ax,w insert_mode    ;load insert flag
  215.         or ax,ax    ;is it?
  216.         je >b1    ;set chart entry flag if not
  217.         call make_insert_box_child    ;check if old box is child of subchart
  218.         mov b chart_flag,3    ;set chart entry flag
  219.         stc    ;exit to start of chart loop
  220.         ret    ;exit
  221.  
  222.         ;set chart entry flag and exit
  223.  
  224. b1:
  225.         mov ax,w temp2    ;load flag
  226.         cmp ax,3    ;prompt for descripter string?
  227.         je >a1    ;set chart entry flag if yes
  228.         mov b chart_flag,al    ;set chart entry flag
  229.         stc    ;exit to chart
  230.         ret
  231.  
  232.         ;set chart entry flag and exit
  233.  
  234. a1:
  235.         mov b chart_flag,2    ;set chart entry flag
  236.         mov b box_made,0    ;dont prompt for new box
  237.         stc    ;exit to chart
  238.         ret
  239.  
  240.         ;link option
  241.  
  242. link_option:
  243.         mov b new_chart,0    ;indicate chart changed
  244.         mov bx,w route    ;load current route offset
  245.         cmp w key_option,1*2    ;is key option link?
  246. if e        jmp long >c1    ;link subchart if it is
  247.         cmp w insert_mode,0    ;are any boxes being inserted?
  248.         je >b1    ;check for subchart if not
  249.         xchg bp,w box_save    ;restore current box
  250.         mov w first_route,bx    ;store current route offset
  251.  
  252.         ;check if subchart is being copied
  253.  
  254. b1:
  255.         cmp w box_to_subchart,0    ;is it?
  256.         jne >a1    ;link it to neighbour boxes if it is
  257.  
  258.         ;link inserted box to current box
  259.  
  260.         mov ax,w box_save    ;load inserted box
  261.         mov dx,bp    ;load new box
  262.         call store_box_par    ;write it to current route
  263.         mov w temp2,4    ;set flag
  264.  
  265.         ;restore current box and exit to chart loop
  266.  
  267.         mov si,bp    ;load box after inserted box
  268.         xor bp,bp    ;load zero
  269.         mov w message,bp    ;clear message buffer
  270.         xchg bp,w box_save    ;restore current box
  271.         jmp check_decision_flag    ;check decision flag and exit
  272.  
  273.         ;link subchart to neighbour boxes
  274.  
  275. a1:
  276.         mov ax,w box_to_subchart    ;load subchart leading neighbour box
  277.         mov si,ax    ;save it
  278.         mov dx,w next_box    ;load new box
  279.         cmp ax,-1    ;is there a neighbour box?
  280.         jne >a1    ;link it if there is
  281.         mov ax,w subchart_link    ;load box to link subchart to
  282.         inc si    ;clear leading neighbour route
  283.         jmp >a2    ;link it to subchart
  284.  
  285.         ;link route of leading neighbour box to new box
  286.  
  287. a1:
  288.         call get_box    ;get its pointer
  289.         mov bx,w route_to_subchart    ;load its route
  290.     es    mov ax,w[di+bx]    ;load box that it points to
  291.     es    mov w[di+bx],dx    ;point leading box to subchart
  292. a2:
  293.         xor bx,bx    ;load previous route offset
  294.         call store_box_par    ;link subchart to following box
  295.  
  296.         ;create new box
  297.  
  298.         mov w route,ax    ;save following box
  299.         call make_box    ;create new box
  300.     es    mov w[di],si    ;store leading neighbour box
  301.         mov bx,child    ;load element offset
  302.         call get_current_box_par    ;get first box in subchart
  303.     es    mov w[di+bx],ax    ;point new box to it
  304.  
  305.         ;copy descripter pointer
  306.  
  307.         mov bx,descripter_length    ;load offset to descripter pointer
  308. a1:
  309.         call get_current_box_par    ;get parameter
  310.     es    mov w[di+bx],ax    ;copy it
  311.         add w start_free_memory,ax    ;raise ram top
  312.         adc w start_free_memory+2,0
  313.  
  314.         ;copy descripter string
  315.  
  316.     es    mov ax,w[di+descripter]    ;copy address
  317.     es    mov dx,w[di+descripter+2]
  318.         push di,es    ;save pointer to new box
  319.         call get_pointer    ;get destination pointer
  320.         mov ax,bp    ;load subchart
  321.         call get_box_descripter    ;get its descripter pointer
  322.         rep
  323.         movsb    ;copy descripter string
  324.         mov ds,ax,cs    ;restore data segment register
  325.         pull es,di    ;restore pointer to new box
  326.  
  327.         ;copy parent of leading neighbour box to new box
  328.  
  329.         mov ax,w subchart_link    ;load following neighbour box
  330.         mov bx,parent    ;load offset to element
  331.         call get_box_par    ;get parent of neighbour box
  332.     es    mov w[di+bx],ax    ;store it in new box
  333.  
  334.         ;copy routes of subchart to new box
  335.  
  336.         mov bx,no    ;load offset to route element
  337.         xor si,si    ;clear route count
  338.         xor dx,dx    ;clear first route
  339.  
  340.         ;check if route exists in subchart
  341.  
  342. a1:
  343.         mov w[si+option_routes],0    ;clear extra route
  344.         call get_current_box_par    ;get route
  345.         or ax,ax    ;is there one?
  346.         je >a2    ;decrement loop count if not
  347.         cmp ax,1    ;is it decision box marker?
  348.         je >a3    ;store it if it is
  349.  
  350.         ;indicate route exists but points to nowhere
  351.  
  352.         mov ax,w next_box    ;copy next box
  353.         mov dx,bx    ;save route
  354.         inc si    ;increment route count
  355.         mov w[bx+option_routes],1    ;indicate route is available option
  356. a3:
  357.     es    mov w[di+bx],ax
  358. a2:
  359.         sub bx,2    ;move to next route
  360.         jne a1    ;decrement loop count
  361.         mov bp,w next_box    ;load copied subchart
  362.         mov bx,dx    ;load route offset
  363.         cmp si,1    ;is there more than one route?
  364.         je >c1    ;link new box to route box if not
  365.  
  366.         ;prompt for route from subchart
  367.  
  368.         mov w key_option,1*2    ;store key option
  369.         mov w box_save,1    ;set flag
  370.         mov w current_route,bx    ;store first route
  371.         call write_message    ;write bottom line prompt to buffer
  372.         db 'Select which route from subchart to link',0
  373.         jmp set_mode_2    ;set mode and exit to chart loop
  374.  
  375.         ;point route from subchart to following neighbour box
  376.  
  377. c1:
  378.         mov dx,w subchart_link    ;copy following box to new box route
  379.         call store_current_box_par    ;point subchart route to following box
  380.         xor ax,ax    ;load zero
  381.         mov w key_option,ax    ;clear key option
  382.         mov w box_save,ax    ;clear flag
  383.         mov w insert_mode,ax    ;clear mode
  384.         mov w box_to_subchart,ax    ;clear box to subchart
  385.         mov b message,al    ;clear message buffer
  386.         mov b chart_flag,2    ;set flag
  387.         mov b box_made,al    ;indicate box created
  388.  
  389.         ;check if box after inserted box is child box of subchart
  390.  
  391.         xchg w subchart_link,ax    ;clear subchart follow box
  392.         mov si,ax    ;load new child box
  393.         mov dx,first_box-1    ;new box marker hasnt been incremented
  394.         call make_insert_box_child2    ;check for any references to old box
  395.         stc    ;exit to start of chart loop
  396.         ret
  397.  
  398.         ;check if sufficient memory
  399.  
  400. check_memory:
  401.         push ax,dx    ;save registers
  402.         call get_available_memory    ;get memory available
  403.         jc >e1    ;exit if overflow
  404.         or dx,dx    ;is there plenty available memory?
  405.         jne >a1    ;create box if there is
  406.         cmp ax,box_record+128    ;is there enough memory for new box
  407.         jae >a1    ;exit if there is
  408.  
  409.         ;exit
  410.  
  411. e1:
  412.         pull dx,ax    ;restore registers
  413.         jmp memory_error    ;exit if not
  414. a1:
  415.         pull dx,ax    ;restore registers
  416.         ret    ;exit
  417.  
  418.         ;check if option is 'create' or 'cancel'
  419.  
  420. create_box:
  421.         mov ax,w box_save    ;load flag
  422.         or ax,ax    ;is option 'create'?
  423.         je >b1    ;create box if it is
  424.         mov bp,ax    ;restore main box
  425.         xor ax,ax    ;clear register
  426.         mov w box_save,ax    ;clear main box save store
  427.         mov w box_to_subchart,ax    ;clear flag
  428.         mov w key_option,ax    ;clear key option store
  429.         mov b message,al    ;clear bottom line message buffer
  430.         mov b chart_flag,4    ;store flowchart entry flag
  431.         stc    ;exit to start of chart loop
  432.         ret    ;exit
  433.  
  434.         ;check if sufficient memory for new box
  435.  
  436. b1:
  437.         mov bx,w route    ;load current route
  438.         mov dx,w next_box    ;load next available box
  439.         call store_current_box_par    ;point current route to new box
  440.         mov w temp2,2    ;prompt for descripter string
  441.         jmp check_decision_flag    ;set decision flag if decision box
  442.  
  443.         ;save current box
  444.  
  445. branch:
  446.         mov w box_save,bp    ;save current box
  447.         mov w link_box,bp    ;store current box as link box
  448.         call write_message    ;write branch message to message buffer
  449.         db 'Choose box to branch to',0
  450.         mov b chart_flag,1    ;store chart entry flag
  451.         stc    ;exit to chart loop
  452.         ret
  453.  
  454.         ;renumber chart
  455.  
  456. renumber:
  457.         mov w temp3,bp    ;save current box
  458. a1:
  459.         call move_to_first_box    ;move to first box in chart
  460.         mov bx,parent    ;load parent route offset
  461.         call get_current_box_par    ;get parent of this chart
  462.         or ax,ax    ;top level?
  463.         je >a2    ;initialise box counter if it is
  464.  
  465.         ;move to next chart up
  466.  
  467.         mov bp,ax    ;load box of parent chart
  468.         jmp a1    ;move to start of next chart if not
  469. a2:
  470.         mov w temp2,first_box    ;store first box number
  471.         mov w temp1,sp    ;save stack pointer
  472.  
  473.         ;if box is current box note new id
  474.  
  475. b1:
  476.         mov dx,w temp2    ;load new box number
  477.         or dh,080h    ;indicate current box redirected
  478.         cmp bp,w temp3    ;is this box current box?
  479. if e        mov w temp3,dx    ;mark new box number
  480.  
  481.         ;check bookmarks
  482.  
  483.         mov cx,10    ;load bookmark count
  484.         mov si,o bookmarks-2    ;load offset to bookmarks
  485. a1:
  486.         inc si,si    ;move to next bookmark
  487.         cmp w[si],bp    ;is current box a bookmark?
  488. if e        mov w[si],dx    ;redirect it if it is
  489.         loop a1    ;decrement loop count
  490.         and dx,07fffh    ;load new box number
  491.         mov bx,box_temp    ;load offset to box temporary store
  492.         call store_current_box_par    ;store boxes new number/offset
  493.  
  494.         ;check for subchart
  495.  
  496.         call get_current_routes    ;get total real routes
  497.         mov ax,w routes+child    ;load child element
  498.         or ax,ax    ;is there one?
  499.         je >a1    ;push any fixed routes if not
  500.         push ax    ;save subchart on stack
  501.         mov bx,parent    ;get parent of subchart
  502.         call get_box_par
  503.         cmp ax,bp    ;is current box a step parent?
  504. if ne        pull ax    ;clear subchart from stack
  505.  
  506.         ;push any fixed routes onto stack
  507.  
  508. a1:
  509.         mov si,no    ;load offset to no route
  510.         xor bx,bx    ;load previous route offset
  511. a1:
  512.         mov ax,w[si+routes]    ;load route
  513.         cmp ax,first_box    ;is it a box route?
  514.         jb >a2    ;move to next route if not
  515.  
  516.         ;check if route is unique
  517.  
  518.         cmp ax,w[si+routes+2]    ;is this route same as 'no' route?
  519.         je >a2    ;ignore this route if it is
  520.         push ax    ;save box route
  521.         call get_box_par    ;get previous route of box route
  522.         cmp ax,bp    ;does it point to current box?
  523. if ne        pull ax    ;clear box from stack
  524. a2:
  525.         sub si,2    ;move to next route
  526.         jne a1    ;check next route if not finished
  527.  
  528.         ;check if any more boxes on stack
  529.  
  530.         or dh,080h    ;set high bit in number
  531.         call check_references    ;replace all references with new box
  532.         cmp sp,w temp1    ;is there?
  533.         je >a1    ;reorder flowchart if not
  534.         pull bp    ;load next current box
  535.         inc w temp2    ;move to new box number
  536.         jmp b1    ;check for any references to current box
  537.  
  538.         ;sort boxes
  539.  
  540. a1:
  541.         inc w temp2    ;increment last box stored
  542.         mov ax,w next_box    ;calculate number of boxes to sort -1
  543.         sub ax,first_box+1
  544.         je >c1    ;check if any blank boxes if just one
  545.         mov w temp1,ax
  546.  
  547.         ;get pointer to start of chart
  548.  
  549. b1:
  550.         mov cx,temp1    ;load box count
  551.         mov ax,first_box    ;load first box parameter
  552.         call get_box    ;get pointer to it
  553.         mov si,di    ;copy it
  554.         add si,box_record    ;point ds:si to next box record
  555.         mov ds,ax,es    ;copy segment
  556.         xor dx,dx    ;clear swap flag
  557.  
  558.         ;swap box records if second box number/offset is lower than first
  559.  
  560. b2:
  561.         mov ax,w[si+box_temp]    ;load box number/offset of second box
  562.     es    cmp ax,w[di+box_temp]    ;is its new position before first box?
  563.         ja >b3    ;move to next
  564.         mov bx,box_temp    ;load top element in record
  565.         or dx,bx    ;indicate swap taken place
  566.  
  567.         ;swap records
  568.  
  569. a1:
  570.         mov ax,w[si+bx]    ;load second box parameter
  571.     es    xchg ax,w[di+bx]    ;exchange it with first box
  572.         mov w[si+bx],ax
  573.         sub bx,2    ;move to next element
  574.         jnc a1    ;exchange next element if no borrow
  575.  
  576.         ;move to next box record
  577.  
  578. b3:
  579.         call add_record2    ;move to next record
  580.         loop b2    ;decrement middle loop count
  581.         mov ds,ax,cs    ;restore data segment register
  582.         or dx,dx    ;any swaps?
  583.         je >c1    ;check if any empty boxes if not
  584.         dec w temp1    ;are boxes sorted?
  585.         jne b1    ;sort again if not
  586.  
  587.         ;delete any blank boxes
  588.  
  589. c1:
  590.         mov ax,w next_box    ;load next new box
  591.         cmp ax,w temp2    ;are there any blank boxes?
  592.         je >b1    ;exit if not
  593.  
  594.         ;calculate size of block to move
  595.  
  596.         mov bx,w start_free_memory    ;copy top of data address
  597.         mov w shift_count,bx
  598.         mov bx,w start_free_memory+2
  599.         mov w shift_count+2,bx
  600.         call get_box_address    ;get source address
  601.         sub w shift_count,ax    ;calculate size of block
  602.         sbb w shift_count+2,dx
  603.         push ax,dx    ;save it
  604.         mov bx,ax
  605.         mov cx,dx
  606.         call get_pointer    ;convert it to pointer format
  607.         mov si,di    ;copy it to source pointer
  608.  
  609.         ;get destination pointer
  610.  
  611.         mov ax,w temp2    ;load destination box number
  612.         mov w next_box,ax
  613.         call get_box_address    ;get destination address
  614.         mov bp,es    ;copy source segment
  615.         mov ds,bp
  616.         call get_pointer    ;convert destination address to pointer
  617.         sub ax,bx    ;calculate correction
  618.         sbb dx,cx
  619.         push ax,dx    ;save it
  620.         call shift_down    ;shift descripter strings
  621.         mov ds,ax,cs    ;restore data segment register
  622.  
  623.         ;update box descripter addresses
  624.  
  625.         pull si,bx,dx,ax    ;restore correction and address
  626.         call update_descripters    ;update descripter addresses
  627.  
  628.         ;clear high bits from route/parent/child pointers
  629.  
  630. b1:
  631.         mov ax,first_box    ;get pointer to first box
  632.         call get_box
  633.         mov cx,w next_box    ;calculate number of boxes
  634.         sub cx,ax
  635. a1:
  636.         mov bx,parent    ;load top element
  637.  
  638.         ;strip bit 15 in each route
  639.  
  640. a2:
  641.     es    and w[di+bx],07fffh    ;get rid of high bit
  642.         sub bx,2    ;decrement inner loop count
  643.         jnc a2
  644.         call add_record    ;move to next box
  645.         loop a1    ;decrement outer loop count
  646.  
  647.         ;restore bookmarks
  648.  
  649.         mov ax,07fffh    ;clear high bits of each bookmark
  650.         mov si,o bookmarks    ;load offset to bookmarks
  651.         mov cx,10
  652. a1:
  653.         and w[si],ax    ;clear high bit of bookmark
  654.         inc si,si    ;move to next bookmark
  655.         loop a1    ;decrement loop count
  656.  
  657.         ;make current box first box and exit
  658.  
  659.         mov w sub_stack,top_stack    ;reset subchart stack
  660.         mov bp,w temp3    ;load first box
  661.         and bp,ax
  662.         mov b chart_flag,1    ;set chart entry flag
  663.         stc    ;exit to start of chart loop
  664.         ret
  665.  
  666.         ;reset chart flags
  667.  
  668. reset_chart_flags_lo:
  669.         mov ax,first_box    ;load first box number
  670.         call get_box    ;get pointer to it
  671.         mov cx,w next_box    ;calculate box count
  672.         sub cx,ax
  673. a1:
  674.     es    mov b[di+box_temp],-1    ;clear flag
  675.         call add_record    ;move to next box
  676.         loop a1    ;decrement loop count
  677.         ret    ;exit
  678.  
  679.         ;reset chart flags
  680.  
  681. reset_chart_flags_hi:
  682.         mov ax,first_box    ;load first box number
  683.         call get_box    ;get pointer to it
  684.         mov cx,w next_box    ;calculate box count
  685.         sub cx,ax
  686. a1:
  687.     es    mov b[di+box_temp+1],-1    ;clear flag
  688.         call add_record    ;move to next box
  689.         loop a1    ;decrement loop count
  690.         ret    ;exit
  691.  
  692.         ;move to first box in chart
  693.  
  694. move_to_first_box:
  695.         call reset_chart_flags_lo    ;flag all boxes unchecked
  696.         xor bx,bx    ;load offset to leading box route
  697.         mov ax,bp    ;load current box
  698.  
  699.         ;check if box is first in chart/sub-chart
  700.  
  701.         mov bx,parent    ;load offset to parent route
  702.         call get_box_par    ;get parent box of current chart
  703.         mov dx,ax
  704.         mov ax,first_box    ;load id of first box in chart
  705.         call get_box    ;get pointer to it
  706.         mov cx,w next_box    ;calulate number of boxes
  707.         sub cx,ax
  708.         jmp >a2    ;don't move pointer
  709.  
  710.         ;get first box in chart id
  711.  
  712. a1:
  713.         inc ax    ;increment box marker
  714.         call add_record    ;move to next box record
  715. a2:
  716.     es    cmp w[di+bx],dx    ;is this box target parent chart box?
  717. if e    es    cmp w[di],0    ;is this first box in its chart?
  718.         loopne a1    ;move to next box if not
  719.  
  720.         ;check if at start of chart
  721.  
  722.         mov w temp1+2,ax    ;store first box id
  723.         mov ax,bp    ;load current box
  724. c1:
  725.         mov bp,ax    ;save box id
  726.         mov dx,w temp1+2    ;load first box id
  727.         sub dx,bp    ;first box in chart?
  728.         je ret    ;exit if it is
  729.  
  730.         ;check if box has been marked
  731.  
  732.         xor bx,bx    ;load offset to previous route
  733.         call get_box_par    ;get leading neighbour box
  734.         mov si,ax    ;save id of marked box
  735.         mov bx,box_temp    ;load offset to flag
  736.         call get_box_par    ;get flag
  737.         or al,al    ;has this box been checked?
  738.         je >c2    ;find alternative route to it if it has
  739.  
  740.         ;mark this box and move to next leading neighbour box
  741.  
  742.         mov ax,si    ;load neighbour box id
  743.         mov bx,box_temp    ;load offset to flag
  744.         mov dx,0ff00h    ;mark this box
  745.         call store_box_par    ;get flag
  746.         jmp c1    ;check next box
  747.  
  748.         ;find link from start of chart to current box
  749.  
  750. c2:
  751.         call reset_chart_flags_hi    ;flag all boxes unchecked
  752.         mov ax,w temp1+2    ;load first box in this chart
  753.         mov dx,bp,si    ;load box to find reference to
  754.         call find_box_to_box    ;check if alternative route to box
  755.         jc >a1    ;move to next box in chain if not found
  756.  
  757.         ;redirect neighbour box
  758.  
  759.         xor bx,bx    ;load offset to neighbour box route
  760.         mov dx,si    ;load box linked from start of chart
  761.         call store_current_box_par    ;redirect current box to linked box
  762. a1:
  763.         mov ax,bp    ;load current box
  764.         jmp c1    ;move to neighbour box
  765.  
  766.         ;check if box is standalone in a sub-chart
  767.  
  768. b2:
  769.     es    cmp w[di+previous],first_box    ;is box at head of chart/sub-chart?
  770.         jae >b3    ;check routes if not
  771.     es    mov ax,w[di+child]    ;is box parent to subchart?
  772.     es    mov bx,w[di+parent]    ;save parent box
  773.         call get_box    ;get box pointer
  774.     es    cmp bp,w[di+parent]    ;is child maternal chart?
  775.         jne >b3    ;exit with error if not
  776.  
  777.         ;check if parent box is maternal
  778.  
  779.         xchg ax,bx    ;copy parent box
  780.         call get_box    ;get box pointer
  781.     es    cmp bp,w[di+child]    ;is box maternal parent?
  782.         jne >b3    ;exit with error if not
  783.     es    mov w[di+child],bx    ;link current box parent to box child
  784.         call get_current_box    ;copy routes for current box
  785.         xor bx,bx    ;load zero
  786.     es    xchg bx,w[di+parent]    ;load parent of current box
  787.  
  788.         ;redirect all parent chart references to parent of current box
  789.  
  790.         mov ax,first_box    ;load first box number
  791.         call get_box    ;get pointer to it
  792.         mov cx,w next_box    ;calculate box count
  793.         sub cx,ax
  794. a1:
  795.     es    cmp w[di+parent],bp    ;is box child to current box?
  796. if e    es    mov w[di+parent],bx    ;redirect it to current box if it is
  797.         call add_record    ;move to next box
  798.         loop a1    ;decrement loop count
  799.  
  800.         ;make first box in child subchart current box
  801.  
  802.         call get_current_box    ;get pointer to current box
  803.     es    mov bp,w[di+child]    ;make current box child box
  804.     es    mov w[di],-1    ;indicate box deleted
  805.     es    mov w[di+box_temp],-1    ;make sure this box will end up at the
  806.         mov b new_chart,0    ;indicate chart changed
  807.         mov b chart_flag,4    ;set chart entry flag
  808.         stc    ;exit to chart loop
  809.         ret
  810.  
  811.         ;delete current box
  812.  
  813. delete_box:
  814.         call get_current_box    ;copy routes for current box
  815.         cmp w real_routes,1    ;is there more than 1 route
  816.         je >b1    ;delete box if not
  817.         jb b2    ;check routes if not
  818.  
  819.         ;check if deleting route will split chart up
  820.  
  821. b3:
  822.         mov bx,no    ;check if no, no route will split chart
  823. a1:
  824.         call store_save_route    ;save and clear route
  825.         jb >a2    ;check yes route if it doesn't go to box
  826.         push bx,bp    ;save route offset
  827.         mov w route,bx    ;store route to be checked
  828.         call will_box_be_missed    ;will deleted box split up chart?
  829.         pull bp,bx    ;restore route offset
  830.         jc ret    ;exit if chart will be split up
  831.         call store_current_box_par    ;restore route in dx to current box
  832. a2:
  833.         dec bx,bx    ;move to next route
  834.         jne a1    ;check it out
  835.  
  836.         ;check if current box is at start of chart
  837.  
  838. b1:
  839.         xor bx,bx    ;load neighbour box offset
  840.         call get_current_box_par    ;get current box routes
  841.         mov w temp1,ax    ;save it
  842.         or ax,ax    ;is there one?
  843.         je >c1    ;delete box if not
  844.         mov dx,ax    ;save box of neighbour route
  845.         call get_routes    ;get its routes
  846.         xor bx,bx    ;start with yes route
  847.  
  848.         ;move to neighbour box joining route
  849.  
  850. a1:
  851.         add bx,2    ;move to next route
  852.         cmp w[bx+routes],bp    ;is neighbour box route joining route?
  853.         jne a1    ;check next route if not
  854.         mov w route_select,bx    ;save route
  855.  
  856.         ;get following neighbour box
  857.  
  858.         mov bx,w first_route    ;load fixed route element
  859.         call get_current_box_par    ;get box of current box
  860.         cmp ax,w temp1    ;is it a outstanding route?
  861. if e        xor ax,ax    ;clear route
  862.  
  863.         ;check if previous neighbour box is decision box
  864.  
  865.         mov bx,w route_select    ;load leading neighbour box route
  866.         cmp bx,no    ;is neighbour route 'no'?
  867.         jb >a1    ;check for any branches if not
  868.         cmp w routes+yes,0    ;is there a yes or no route?
  869.         je >a1    ;check for any branches if not
  870.         cmp w routes+no,0    ;is box decision box?
  871.         je >a1    ;check for branches if not
  872.  
  873.         ;check if box will point to itself
  874.  
  875.         cmp ax,dx    ;will box point to itself?
  876. if e        xor ax,ax    ;clear route if it will
  877.         or ax,ax    ;will route be linked to trailing box
  878. if e        inc ax    ;flag empty route if not
  879.         jmp >a2    ;store box parameter
  880.  
  881.         ;check if route from current box is fixed route
  882.  
  883. a1:
  884.         or bx,bx    ;is there a route?
  885.         jne >a2    ;line it if there is
  886.         cmp ax,first_box    ;is route to box?
  887. if b        xor ax,ax    ;clear route if not
  888. a2:
  889.         xchg ax,dx    ;exchange neighbour boxes
  890.         mov bx,w route_select    ;load route from neighbour box
  891.         call store_box_par    ;point previous box to following box
  892.  
  893.         ;delete current box
  894.  
  895. c1:
  896.         call get_current_box    ;get pointer to current box
  897.     es    mov w[di],-1    ;indicate box deleted
  898.     es    mov w[di+box_temp],-1    ;make sure this box will end up at the
  899.             ;end of box block when renumbering
  900.         mov b new_chart,0    ;indicate chart changed
  901.  
  902.         ;delete descripter string
  903.  
  904.         mov bx,w start_free_memory    ;calculate size of text block to move
  905.         mov cx,w start_free_memory+2
  906.     es    mov ax,w[di+descripter]    ;load address to descripter string
  907.     es    mov dx,w[di+descripter+2]
  908.         sub bx,ax
  909.         sbb cx,dx
  910.     es    mov si,w[di+descripter_length]
  911.         sub bx,si
  912.         sbb cx,0
  913.         mov w shift_count,bx    ;save size of block
  914.         mov w shift_count+2,cx
  915.  
  916.         ;get source and destination pointers
  917.  
  918.         call get_pointer    ;convert address to pointer
  919.         add ax,si    ;add string size to address
  920.         adc dx,0
  921.         push ax,dx,si    ;save address
  922.         push di,es    ;save pointer
  923.         call get_pointer    ;get source pointer
  924.         mov si,di
  925.         mov ds,ax,es
  926.         pull es,di    ;restore destination pointer
  927.         call shift_down    ;delete descripter string
  928.         mov ds,ax,cs    ;restore data segment register
  929.  
  930.         ;update descripter addresses of other boxes
  931.  
  932.         pull ax    ;restore descripter size
  933.         neg ax    ;make count minus
  934.         cwd
  935.         mov bx,ax    ;save it
  936.         mov si,dx
  937.         pull dx,ax    ;restore address
  938.         call update_descripters    ;update descripter addresses
  939.  
  940.         ;make current box following neighbour box
  941.  
  942.         mov w sub_stack,top_stack    ;clear subchart stack
  943.         mov dx,w temp1    ;load leading neighbour box
  944.         mov bx,w first_route    ;load route offset
  945.         call get_current_box_par    ;get following neighbour box
  946.         cmp dx,ax    ;will box point to itself?
  947. if e        xor ax,ax    ;clear box reference if it will
  948.         push ax    ;make it current box
  949.  
  950.         ;redirect trailing neighbour box
  951.  
  952.         cmp ax,first_box    ;is there a route
  953.         jb >a1    ;exit if not
  954.         call get_box    ;get pointer to box
  955.     es    cmp w[di],0    ;is box first in chart?
  956. if ne    es    mov w[di],dx    ;change its leading neighbour box if not
  957.  
  958.         ;clear any other references to current box
  959.  
  960.         xor ax,ax    ;assume no yes route
  961.     es    cmp w[di+yes],bp    ;does route point to current box?
  962. if e    es    mov w[di+yes],ax    ;clear route if it does
  963.     es    cmp w[di+no],bp    ;does route point to current box?
  964.         jne >a1    ;update remaining boxes if not
  965.     es    cmp w[di+yes],ax    ;is there a yes route?
  966. if ne        inc ax    ;indicate box is decision box it yes
  967.     es    mov w[di+no],ax    ;clear route if it does
  968.  
  969.         ;check if there are any references to deleted box
  970.  
  971. a1:
  972.         pull dx    ;load new box route
  973.         call check_references    ;delete all references to current box
  974.         cmp dx,first_box    ;is route from current box terminator
  975. if b        mov dx,w temp1    ;load leading neighbour box if it is
  976.         mov si,bp    ;load old box
  977.         cmp w real_routes,0    ;is there a fixed route?
  978.         je >b1    ;check if leading neighbour box if not
  979.         mov bp,dx    ;load new box route
  980.  
  981.         ;check if deleted box is at the start of a subchart
  982.  
  983.         or dx,dx    ;is there a leading neighbour box?
  984.         jne >a1    ;exit to chart loop if there is
  985.         mov ax,si    ;load deleted box
  986.         mov bx,parent    ;load offset to parent element
  987.         call get_box_par    ;get deleted boxes parent
  988.         or ax,ax    ;is there one?
  989.         jne >c1    ;check if any step parents if there is
  990. a1:
  991.         mov b chart_flag,4    ;store chart entry flag
  992.         stc    ;exit to start of chart loop
  993.         ret
  994.  
  995.         ;check if any boxes left
  996.  
  997. b1:
  998.         or dx,dx    ;is there a leading neighbour box?
  999.         jne >b1    ;make it current box if there is
  1000.         mov bx,parent    ;load parent element offset
  1001.         call get_current_box_par    ;get parent of deleted box
  1002.         or ax,ax    ;is there one?
  1003.         jne >a1    ;make it current box if there is
  1004.         xor bp,bp    ;indicate exit to menu and clear chart
  1005.         ret
  1006.  
  1007.         ;make parent box of deleted box current box
  1008.  
  1009. a1:
  1010.         mov bp,ax    ;make parent box current box
  1011.         mov bx,child    ;load child element offset
  1012.         call get_current_box_par    ;get child subchart of parent
  1013.         mov si,ax    ;save it
  1014.         jmp >c2    ;clear all references to subchart
  1015.  
  1016.         ;make leading box current box
  1017.  
  1018. b1:
  1019.         mov bp,dx    ;load leading box
  1020.         mov b chart_flag,4    ;set chart loop entry flag
  1021.         stc    ;exit to chart loop
  1022.         ret
  1023.  
  1024.         ;exit to chart loop
  1025.  
  1026. c1:
  1027.         call make_insert_box_child    ;check if old box is child of subchart
  1028.         mov b chart_flag,4    ;set chart entry flag
  1029.         stc    ;exit to chart loop
  1030.         ret
  1031.  
  1032.         ;clear all references to deleted subchart
  1033.  
  1034. c2:
  1035.         mov ax,first_box    ;load first box number
  1036.         call get_box    ;get its pointer
  1037.         mov bx,child    ;load child box element offset
  1038.         mov cx,w next_box    ;calculate box count
  1039.         sub cx,ax
  1040.  
  1041.         ;check child of box
  1042.  
  1043. a1:
  1044.     es    cmp w[di+bx],si    ;is it a step parent of deleted subchart
  1045.         jne >a2    ;decrement loop count if not
  1046.     es    mov w[di+bx],0    ;cnear child status
  1047. a2:
  1048.         call add_record    ;increment box
  1049.         loop a1    ;decrement loop count
  1050.  
  1051.         ;exit to chart loop
  1052.  
  1053.         mov b chart_flag,4    ;set chart entry flag
  1054.         stc    ;exit to chart loop
  1055.         ret
  1056.  
  1057.         ;check if old box is child box of subchart
  1058.  
  1059. make_insert_box_child:
  1060.         mov dx,first_box    ;load first box
  1061.         mov ax,si    ;load old box
  1062. make_insert_box_child2:
  1063.         mov bx,parent    ;load offset to parent element
  1064.         call get_box_par    ;get parent box
  1065.         or ax,ax    ;is there a parent?
  1066.         je ret    ;exit if not
  1067.         mov ax,first_box    ;load first box number
  1068.         call get_box    ;get its pointer
  1069.         mov bx,child    ;load child box element offset
  1070.         mov cx,w next_box    ;calculate box count
  1071.         sub cx,dx
  1072.  
  1073.         ;get box pointer and check its child status
  1074.  
  1075. a1:
  1076.     es    cmp w[di+bx],si    ;does it point to deleted box
  1077.         jne >a2    ;decrement loop count if not
  1078.     es    mov w[di+bx],bp    ;store new current box as child box
  1079. a2:
  1080.         call add_record    ;increment box
  1081.         loop a1    ;decrement loop count
  1082.         ret    ;exit
  1083.  
  1084.         ;replace any references to current box with dx
  1085.  
  1086. check_references:
  1087.         mov ax,first_box    ;load first box number
  1088.         call get_box    ;get pointer to it
  1089.         mov cx,w next_box    ;calculate box count
  1090.         sub cx,ax
  1091. a1:
  1092.     es    cmp w[di],-1    ;is box deleted?
  1093. if ne        call check_routes    ;check if any routes point to box
  1094.         call add_record    ;move to next box
  1095.         loop a1    ;decrement loop count
  1096.         ret    ;exit
  1097.  
  1098.         ;check if any routes point to current box
  1099.  
  1100. check_routes:
  1101.         push cx    ;save register
  1102.         xor si,si    ;clear existing routes marker
  1103.         mov cx,1    ;load loop count
  1104.         mov bx,yes    ;load yes route offset
  1105.     es    cmp w[di+no],0    ;is box decision box?
  1106. if ne        inc cx    ;load loop count
  1107.  
  1108.         ;check if route points to current box
  1109.  
  1110. b1:
  1111.     es    mov ax,w[di+bx]    ;load route
  1112.         or ax,ax    ;is route active?
  1113.         je >b2    ;decrement loop count if not
  1114.         add ax,si    ;add existing route marker to route
  1115.         cmp ax,1    ;is route void?
  1116.         jne >a1    ;check if it points to current box if no
  1117.         or dx,dx    ;is reference deleted box?
  1118.         jne >b3    ;check parent and child pointers if not
  1119.     es    mov w[di+bx],0    ;clear route
  1120.         pull cx    ;restore register
  1121.         ret    ;exit
  1122.  
  1123.         ;check if route points to current box
  1124.  
  1125. a1:
  1126.     es    cmp w[di+bx],bp    ;does it?
  1127.         jne >a2    ;increment existing route if not
  1128.         mov ax,dx    ;load replace box route
  1129.         cmp bx,no    ;is it neither route?
  1130.         jb >a1    ;clear route if not
  1131.         or si,si    ;are there any other routes?
  1132.         je >a1    ;clear route if not
  1133.         or ax,ax    ;is replace box nul?
  1134. if e        inc ax    ;load decision box marker
  1135. a1:
  1136.     es    mov w[di+bx],ax    ;clear route
  1137.         jmp >b2    ;decrement loop count
  1138.  
  1139.         ;increment existing route count
  1140.  
  1141. a2:
  1142.         inc si    ;increment existing route count
  1143. b2:
  1144.         add bx,2    ;move to next route
  1145.         loop b1    ;decrement loop count
  1146.  
  1147.         ;check for references to parent and child pointers
  1148.  
  1149. b3:
  1150.         pull cx    ;restore registers
  1151.         cmp dx,first_box    ;is box being deleted?
  1152.         jb ret    ;exit if it is
  1153.  
  1154.         ;check if leading neighbour box pointer refers to current box
  1155.  
  1156.     es    cmp w[di],bp    ;does it?
  1157. if e    es    mov w[di],dx    ;store new box
  1158.     es    cmp w[di+child],bp    ;is reference box child chart?
  1159. if e    es    mov w[di+child],dx    ;replace reference
  1160.     es    cmp w[di+parent],bp    ;is reference box parent?
  1161. if e    es    mov w[di+parent],dx    ;replace reference
  1162.         ret    ;exit
  1163.  
  1164.         ;end
  1165.